package com.nchu.learn.netty.coder;

import cn.hutool.core.lang.ObjectId;
import com.nchu.learn.netty.enums.MessageTypeEnum;
import com.nchu.learn.netty.model.Constants;
import com.nchu.learn.netty.model.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.Charset;

/**
 * 编码器
 * 将Message对象消息转成byte报文
 *
 * @author fujianjian
 * @project self-learning
 * @date 2020/1/16 10:35
 */
public class MessageEncoder extends MessageToByteEncoder<Message> {

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, Message message, ByteBuf byteBuf) throws Exception {
        // 如果消息类型是不是Empty的，如果是empty类型，则表示当前消息不需要写入管道中
        if (message.getMessageType() != MessageTypeEnum.EMPTY) {
            byteBuf.writeInt(Constants.MAGIC_NUMBER);
            byteBuf.writeByte(Constants.MAIN_VERSION);
            byteBuf.writeByte(Constants.SUB_VERSION);
            byteBuf.writeByte(Constants.MODIFY_VERSION);

            if (StringUtils.isEmpty(message.getSessionId())) {
                message.setSessionId(ObjectId.next());
            }
            byteBuf.writeCharSequence(message.getSessionId(), Charset.defaultCharset());

            byteBuf.writeByte(message.getMessageType().getType());
            byteBuf.writeShort(message.getAttachments().size());

            message.getAttachments().forEach((key, value) -> {
                Charset charset = Charset.defaultCharset();
                byteBuf.writeInt(key.length());
                byteBuf.writeCharSequence(key, charset);
                byteBuf.writeInt(value.length());
                byteBuf.writeCharSequence(value, charset);
            });

            if (StringUtils.isEmpty(message.getBody())) {
                byteBuf.writeInt(0);
            } else {
                byteBuf.writeInt(message.getBody().length());
                byteBuf.writeCharSequence(message.getBody(), Charset.defaultCharset());
            }
        }

    }
}
